www.gusucode.com > 基于Visual C++高级界面特效制作百例源码程序 > 基于Visual C++高级界面特效制作百例源码程序/code/char22/histogram_control/HistogramCtrl.cpp
// HistogramCtrl.cpp : implementation file // // stdafx.cpp : source file that includes just the standard includes // CPanel.pch will be the pre-compiled header // stdafx.obj will contain the pre-compiled type information #include "stdafx.h" #include "HistogramCtrl.h" #ifdef _DEBUG #define new DEBUG_NEW #undef THIS_FILE static char THIS_FILE[] = __FILE__; #endif ///////////////////////////////////////////////////////////////////////////// // CHistogramCtrl CHistogramCtrl::CHistogramCtrl() { m_nPos = 0; m_nLower = 0; m_nUpper = 100; } CHistogramCtrl::~CHistogramCtrl() { } BEGIN_MESSAGE_MAP(CHistogramCtrl, CWnd) //{{AFX_MSG_MAP(CHistogramCtrl) ON_WM_PAINT() //}}AFX_MSG_MAP END_MESSAGE_MAP() ///////////////////////////////////////////////////////////////////////////// // CSpikeCtrl message handlers BOOL CHistogramCtrl::Create(DWORD dwStyle, const RECT& rect, CWnd* pParentWnd, UINT nID, CCreateContext* pContext) { // TODO: Add your specialized code here and/or call the base class static CString className = AfxRegisterWndClass(CS_HREDRAW | CS_VREDRAW); return CWnd::CreateEx(WS_EX_CLIENTEDGE | WS_EX_STATICEDGE, className, NULL, dwStyle, rect.left, rect.top, rect.right-rect.left, rect.bottom-rect.top, pParentWnd->GetSafeHwnd(), (HMENU) nID); } void CHistogramCtrl::SetRange(UINT nLower, UINT nUpper) { ASSERT(nLower >= 0 && nLower < 0xffff); ASSERT(nUpper > nLower && nUpper < 0xffff); m_nLower = nLower; m_nUpper = nUpper; InvalidateCtrl(); } void CHistogramCtrl::InvalidateCtrl() { // Small optimization that just invalidates the client area // (The borders don't usually need updating) CClientDC dc(this); CRect rcClient; GetClientRect(rcClient); if (m_MemDC.GetSafeHdc() == NULL) { m_MemDC.CreateCompatibleDC(&dc); m_Bitmap.CreateCompatibleBitmap(&dc,rcClient.Width(),rcClient.Height()); m_MemDC.SelectObject(m_Bitmap); // draw scale m_MemDC.SetBkColor(RGB(0,0,0)); CBrush bkBrush(HS_HORIZONTAL,RGB(0,128,0)); m_MemDC.FillRect(rcClient,&bkBrush); } InvalidateRect(rcClient); } UINT CHistogramCtrl::SetPos(UINT nPos) { if (nPos > m_nUpper) nPos = m_nUpper; if (nPos < m_nLower) nPos = m_nLower; UINT nOld = m_nPos; m_nPos = nPos; DrawSpike(); Invalidate(); return nOld; } void CHistogramCtrl::OnPaint() { CPaintDC dc(this); // device context for painting // TODO: Add your message handler code here // Do not call CWnd::OnPaint() for painting messages // draw scale CRect rcClient; GetClientRect(rcClient); // draw scale if (m_MemDC.GetSafeHdc() != NULL) { dc.BitBlt(0, 0, rcClient.Width(), rcClient.Height(), &m_MemDC, 0, 0, SRCCOPY); } } void CHistogramCtrl::DrawSpike() { // CClientDC dc(this); UINT nRange = m_nUpper - m_nLower; CRect rcClient; GetClientRect(rcClient); if (m_MemDC.GetSafeHdc() != NULL) { m_MemDC.BitBlt(0, 0, rcClient.Width(), rcClient.Height(), &m_MemDC, 4, 0, SRCCOPY); CRect rcTop(rcClient.right - 4, 0, rcClient.right - 2, rcClient.bottom); rcTop.top = (long) (((float) (m_nPos - m_nLower) / nRange) * rcClient.Height()); rcTop.top = rcClient.bottom - rcTop.top; // draw scale CRect rcRight = rcClient; rcRight.left = rcRight.right - 4; m_MemDC.SetBkColor(RGB(0,0,0)); CBrush bkBrush(HS_HORIZONTAL,RGB(0,128,0)); m_MemDC.FillRect(rcRight,&bkBrush); // draw current spike CBrush brush(RGB(0,255,0)); m_MemDC.FillRect(rcTop, &brush); } }